"""
进程的创建模块：multiprocessing
"""
import os
import time
import multiprocessing


#函数名Process创建一个进程，返回进程对象
#start 执行进程
#join  阻塞程序
#kill  杀死进程
#is_alive 进程是否存活
#通过进程模块执行的函数无法获取返回值

def work_a():
    for i in range(10):
        print(i,'a',os.getpid()) #打印进程id
        time.sleep(1)

def work_b():
    for i in range(10):
        print(i,'b',os.getpid())
        time.sleep(1)

# if __name__ == '__main__':
#     start = time.time() #主进程代码1
#     a_p = multiprocessing.Process(target=work_a) #子进程1
#     a_p.start() #子进程1执行
#     a_p.join()
#     b_p = multiprocessing.Process(target=work_b) #子进程2
#     b_p.start() #子进程2执行
#
#     #可以用for循环批量启动进程
#     # for p in (a_p, b_p):
#     #     p.start()
#
#     #将多进程的程序阻塞，直到a_p,b_p执行完了再执行下面的代码
#     # for p in (a_p, b_p):
#     #     p.join()
#     for p in (a_p,b_p):
#         print(p.is_alive())
#
#     print('时间消耗是: ',time.time() - start) #主进程代码2
#     print(f'parent pid is {os.getpid()}') #主进程代码3

"""
进程池：避免了创建与关闭的消耗
"""

#函数名Pool进程池创建，返回进程池对象
#apply_async任务加入进程池（异步） 无返回值
#close关闭进程池 无返回值
#join等待进程池任务结束 无返回值

def work(count,lock):
    lock.acquire()
    print(count,os.getpid())
    time.sleep(5)
    lock.release()
    return f'result is {count}, pip is {os.getpid()}'
from multiprocessing import Manager
# if __name__ == '__main__':
#     pool = multiprocessing.Pool(5)
#     manager = Manager()
#     lock = manager.Lock()
#     results = []
#     for i in range(20):
#         result = pool.apply_async(func=work,args=(i,lock))
#         results.append(result)
#
#     for res in results:
#         print(res.get()) #获取返回值
#
#     # time.sleep(20) 主进程给予足够的时间执行进程池里的内容，否则程序立即结束，无打印
#     # pool.close() #这两行代码保证了进程池代码执行结束，主进程再结束
#     # pool.join()

"""
进程锁的加锁与解锁
"""
# from multiprocessing import Manager
# manager = Manager()
# lock = manager.Lock()
# lock.acquire() #上锁
# lock.release() #解锁

"""
进程之间的通信
"""

#函数名Queue队列的创建，返回队列对象
#put信息放入队列，参数message，无返回值
#get获取队列信息，无参数，返回str
import json
class Work(object):
    def __init__(self, q):
        self.q = q
    def send(self,message):
        if not isinstance(message,str):
            message = json.dumps(message)
        self.q.put(message)

    def send_all(self):
        for i in range(20):
            self.q.put(i)
            time.sleep(1)

    def receive(self):
        while True:
            result = self.q.get()
            try:
                res = json.loads(result)
            except:
                res = result
            print(f'recv is {res}')

if __name__ == '__main__':
    q = multiprocessing.Queue()
    work = Work(q)
    send = multiprocessing.Process(target=work.send,args=({'name':'winner'},))
    recv = multiprocessing.Process(target=work.receive)
    send_all_p = multiprocessing.Process(target=work.send_all)

    send_all_p.start()
    send.start()
    recv.start()

    send_all_p.join() #执行时间最长的阻塞，保证它能执行完
    recv.terminate() #代码终止